package com.qin.mall.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qin.mall.domain.*;
import com.qin.mall.common.api.CommonResult;
import com.qin.mall.common.constant.AuthConstant;
import com.qin.mall.common.domain.UserDto;
import com.qin.mall.dao.UmsAdminRoleRelationDao;
import com.qin.mall.dto.UmsAdminParam;
import com.qin.mall.dto.UpdateAdminPasswordParam;
import com.qin.mall.exception.Asserts;
import com.qin.mall.mapper.UmsAdminLoginLogMapper;
import com.qin.mall.mapper.UmsAdminRoleRelationMapper;
import com.qin.mall.openfeign.AuthService;
//import com.qin.mall.result.CommonResult;
import com.qin.mall.result.ResultCode;
import com.qin.mall.service.UmsAdminCacheService;
import com.qin.mall.service.UmsAdminService;
import com.qin.mall.mapper.UmsAdminMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 覃剑
* @description 针对表【ums_admin(后台用户表)】的数据库操作Service实现
* @createDate 2022-11-11 09:51:38
*/
@Service
public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper, UmsAdmin>
    implements UmsAdminService{

    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);

    @Autowired
    private UmsAdminMapper adminMapper;
    @Autowired
    private UmsAdminRoleRelationMapper adminRoleRelationMapper;

    @Autowired
    private UmsAdminLoginLogMapper loginLogMapper;
    @Autowired
    private UmsAdminRoleRelationDao adminRoleRelationDao;
    @Autowired
    private AuthService authService;
    @Autowired
    private HttpServletRequest request;
    
    
    
    /**
     * 根据用户名获取后台管理员
     */
    @Override
    public UmsAdmin getAdminByUsername(String username) {
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        List<UmsAdmin> adminList = adminMapper.selectList(wrapper);
        if (adminList != null && adminList.size() > 0) {
            return adminList.get(0);
        }
        return null;
    }

    /**
     * 注册功能
     */
    @Override
    public UmsAdmin register(UmsAdminParam umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        //将给的的对象属性给到目标bean中
        BeanUtil.copyProperties(umsAdminParam,umsAdmin);
        umsAdmin.setCreateTime(new Date());
        //开启账号
        umsAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.eq("username",umsAdmin.getUsername());
        List<UmsAdmin> adminList = adminMapper.selectList(wrapper);
        if (adminList.size()>0){
            System.out.println("您的名称已存在!!!");
            return null;
        }
        //将密码进行加密操作-使用hutool 解密也使用这个
        String encodePassword = BCrypt.hashpw(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        adminMapper.insert(umsAdmin);
        return umsAdmin;
    }

    /**
     * 登录功能
     * @param username 用户名
     * @param password 密码
     * @return 调用认证中心返回结果
     */
    @Override
    public CommonResult login(String username, String password) {
        if(StrUtil.isEmpty(username)||StrUtil.isEmpty(password)){
            Asserts.fail("用户名或密码不能为空！");
        }
        UserDto userDetails = loadUserByUsername(username);
        if(!BCrypt.checkpw(password,userDetails.getPassword())){
            Asserts.fail("密码不正确");
        }
        Map<String, String> params = new HashMap<>();
        params.put("client_id", AuthConstant.ADMIN_CLIENT_ID);
        params.put("client_secret","123456");
        params.put("grant_type","password");
        params.put("username",username);
        params.put("password",password);
        //远程获取token
       CommonResult restResult = authService.getAccessToken(params);
        if(ResultCode.SUCCESS.getCode()==restResult.getCode()&&restResult.getData()!=null){
            insertLoginLog(username);
        }
        return restResult;
    }

    @Override
    public String refreshToken(String oldToken) {
        return null;
    }



    /**
     * 添加登录记录
     * @param username 用户名
     */
    private void insertLoginLog(String username) {
        UmsAdmin admin = getAdminByUsername(username);
        if(admin==null) return;
        UmsAdminLoginLog loginLog = new UmsAdminLoginLog();
        loginLog.setAdminId(admin.getId());
        loginLog.setCreateTime(new Date());
        // 获取当前线程的请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //设置ip地址
        loginLog.setIp(request.getRemoteAddr());
        loginLogMapper.insert(loginLog);
    }

    /**
     * 根据用户id获取用户
     */
    @Override
    public UmsAdmin getItem(Long id) {
        UmsAdmin umsAdmin = adminMapper.selectById(id);
        return umsAdmin;
    }

    /**
     * 根据用户名或昵称分页查询用户
     */
    @Override
    public List<UmsAdmin> list(String keyword, Integer pageNum, Integer pageSize) {
        Page<UmsAdmin> adminPage = new Page<>(pageNum, pageSize);
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();

        if (StrUtil.isNotEmpty(keyword)){
            wrapper.like("username",keyword)
                    .or()
                    .like("nick_name",keyword);
        }
//        Page<UmsAdmin> page = adminMapper.selectPage(adminPage, wrapper);
        List<UmsAdmin> list = adminMapper.selectList(wrapper);
        
        return list;
    }

    /**
     * 修改指定用户信息,修改密码
     */
    @Override
    public int update(Long id, UmsAdmin admin) {
        admin.setId(id);
        UmsAdmin rawAdmin = adminMapper.selectById(id);
        if (rawAdmin.getPassword().equals(admin.getPassword())){
            //密码相同则不用修改
            admin.setPassword(null);
        }else{
            //修改密码
            // 如果传入的密码是null 也不用修改
            if (StrUtil.isEmpty(admin.getPassword())){
                admin.setPassword(null);
            }
            else{
                admin.setPassword(BCrypt.hashpw(admin.getPassword()));
            }
        }
        //更新操作
        int count = adminMapper.updateById(admin);
        getCacheService().delAdmin(id);

        return count;
    }

    /**
     * 删除指定用户
     */
    @Override
    public int delete(Long id) {
        // 要删除用户先删除redis 里面的数据
        getCacheService().delAdmin(id);
        int count = adminMapper.deleteById(id);
        //
//        getCacheService().delResourceList(id);
        return count;
    }

    /**
     * 修改用户角色关系
     */
    @Override
    public int updateRole(Long adminId, List<Long> roleIds) {
        int count = roleIds == null ? 0 : roleIds.size();
        //先删除原来的关系
        QueryWrapper<UmsAdminRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("admin_id",adminId);
        int delete = adminRoleRelationMapper.delete(wrapper);
        //建立新关系
        if (!CollectionUtils.isEmpty(roleIds)){
            ArrayList<UmsAdminRoleRelation> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                UmsAdminRoleRelation roleRelation = new UmsAdminRoleRelation();
                roleRelation.setAdminId(adminId);
                roleRelation.setRoleId(roleId);
                list.add(roleRelation);
            }
            //插入用户角色关系
            adminRoleRelationDao.insertList(list);
        }
//        getCacheService().delResourceList(adminId);
        return count;
    }

    /**
     * 获取用户对应角色
     */
    @Override
    public List<UmsRole> getRoleList(Long adminId) {
        List<UmsRole> list = adminRoleRelationDao.getRoleList(adminId);
        return list;
    }

    /**
     * 获取指定用户的可访问资源
     */
    @Override
    public List<UmsResource> getResourceList(Long adminId) {
        List<UmsResource> resourceList = getCacheService().getResourceList(adminId);
        if(CollUtil.isNotEmpty(resourceList)){
            return  resourceList;
        }
        resourceList = adminRoleRelationDao.getResourceList(adminId);
        if(CollUtil.isNotEmpty(resourceList)){
            getCacheService().setResourceList(adminId,resourceList);
        }
        return resourceList;
    }

    /**
     * 修改密码
     */
    @Override
    public int updatePassword(UpdateAdminPasswordParam param) {
        if(StrUtil.isEmpty(param.getUsername())
                ||StrUtil.isEmpty(param.getOldPassword())
                ||StrUtil.isEmpty(param.getNewPassword())){
            return -1;
        }
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.eq("username",param.getUsername());
        List<UmsAdmin> adminList = adminMapper.selectList(wrapper);
        if(CollUtil.isEmpty(adminList)){
            return -2;
        }
        UmsAdmin umsAdmin = adminList.get(0);
        if(!BCrypt.checkpw(param.getOldPassword(),umsAdmin.getPassword())){
            return -3;
        }
        umsAdmin.setPassword(BCrypt.hashpw(param.getNewPassword()));
        adminMapper.updateById(umsAdmin);
        getCacheService().delAdmin(umsAdmin.getId());
        return 1;
    }
    
    
    
    /**
     * 获取用户信息
     */
    @Override
    public UserDto loadUserByUsername(String username) {
        //获取用户信息
        UmsAdmin admin = getAdminByUsername(username);
        if (admin != null) {
            List<UmsRole> roleList = getRoleList(admin.getId());
            UserDto userDTO = new UserDto();
            BeanUtils.copyProperties(admin,userDTO);
            if(CollUtil.isNotEmpty(roleList)){
                List<String> roleStrList = roleList.stream().map(item -> item.getId() + "_" + item.getName()).collect(Collectors.toList());
                userDTO.setRoles(roleStrList);
            }
            return userDTO;
        }
        return null;
    }


    @Override
    public UmsAdmin getCurrentAdmin() {
        String userStr = request.getHeader(AuthConstant.USER_TOKEN_HEADER);
        if(StrUtil.isEmpty(userStr)){
            Asserts.fail(ResultCode.UNAUTHORIZED);
        }
        UserDto userDto = JSONUtil.toBean(userStr, UserDto.class);
        UmsAdmin admin = getCacheService().getAdmin(userDto.getId());
        if(admin!=null){
            return admin;
        }else{
            admin = adminMapper.selectById(userDto.getId());
            getCacheService().setAdmin(admin);
            return admin;
        }
    }

    /**
     * 获取缓存服务
     */
    @Override
    public UmsAdminCacheService getCacheService() {
        return SpringUtil.getBean(UmsAdminCacheService.class);
    }
}




